package com.kuaimacode.kframework.api.controller.pay;

import com.kuaimacode.kframework.api.controller.BaseController;
import com.kuaimacode.kframework.api.service.*;
import com.kuaimacode.kframework.api.service.user.OrderDispatchService;
import com.kuaimacode.kframework.api.service.user.OrderEvaluateService;
import com.kuaimacode.kframework.api.service.user.OrderService;
import com.kuaimacode.kframework.api.vo.response.WxPrePayResp;
import com.kuaimacode.kframework.common.Constant;
import com.kuaimacode.kframework.common.JsonResult;
import com.kuaimacode.kframework.constants.MasterConstants;
import com.kuaimacode.kframework.exception.ErrorEnum;
import com.kuaimacode.kframework.exception.ServerInternalErrorException;
import com.kuaimacode.kframework.mybatis.models.master.MasterOrderAccitity;
import com.kuaimacode.kframework.mybatis.models.user.*;
import com.kuaimacode.kframework.util.CommonUtil;
import com.kuaimacode.kframework.util.DictUtil;
import com.kuaimacode.kframework.util.PayCommonUtil;
import com.kuaimacode.kframework.util.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import weixin.popular.api.PayMchAPI;
import weixin.popular.bean.paymch.SecapiPayRefund;
import weixin.popular.bean.paymch.SecapiPayRefundResult;
import weixin.popular.client.LocalHttpClient;
import weixin.popular.util.MapUtil;
import weixin.popular.util.SignatureUtil;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.*;

@RestController
@RequestMapping("/wxpay")
@Api(tags = "微信支付相关",description = "微信支付相关")
public class WxpayController  extends BaseController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private OrderService orderService;

    @Autowired
    private MasterOrderAccitityService accitityService;

    @Autowired
    private OrderEvaluateService orderEvaluateService;

    @Autowired
    private UserService userService;
    @Autowired
    private UserAccountDetailService userAccountDetailService;
    @Autowired
    private SysMessageService sysMessageService;
    @Autowired
    private UserRechargeService userRechargeService;
    @Autowired
    private OrderDispatchService orderDispatchService;


    // 获取配置文件中微信相关信息
    @Value("${pay.wxpay.appId}")
    private String appId;
    @Value("${pay.wxpay.appSecret}")
    private String appSecret;
    @Value("${pay.wxpay.mchId}")
    private String mchId;
    @Value("${pay.wxpay.apiKey}")
    private String apiKey;
    @Value("${pay.wxpay.notify}")
    private String notify;


    /** 商户支付证书路径 */
    //private final String API_CLIENT_CERT_PATH = "/Users/mac/Downloads/cert/apiclient_cert.p12";
    @Value("${pay.wxpay.cert}")
    private String API_CLIENT_CERT_PATH;


    @ApiOperation(value = "生成APP支付订单信息", notes="生成APP支付订单信息")
    @PostMapping("/prepare")
    @ApiImplicitParam(name = "orderNo", value = "订单号", required = true, dataType = "string")
    @Transactional
    public JsonResult prepare(@RequestParam String orderNo,
                              HttpServletRequest request){
        // 查询订单
        Order order = orderService.findOrderByOrderNo(orderNo);
        Optional.ofNullable(order).filter(o->o.getStatus() == Constant.OrderStatusEnum.WAIT_PAY.getCode())
                .orElseThrow(()->new ServerInternalErrorException(ErrorEnum.ORDER_NOT_EXIST));
        String trade_no = "";
        String description="阿四服务订单-";
        try {
            trade_no = new String(order.getOutTradeNo().getBytes("ISO-8859-1"),"UTF-8");
            if(order.getHasPartner() == 1){
                description = description+"合作商家订单";
            }else{
                String type = DictUtil.keyValue("SERVICE_CLASS",order.getType()+"");
                String childTypeCode = "SERVICE_CLASS_"+order.getType();
                String childType = DictUtil.keyValue(childTypeCode,order.getChildType()+"");
                description = description+type+"-"+childType;
            }
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String openId = "";
        Map<String, String> map = weixinPrePay(trade_no,order.getAmount(),description,openId,request, "APP");
        SortedMap<String, Object> finalpackage = new TreeMap<String, Object>();
        //应用ID
        finalpackage.put("appid", appId);
        //商户号
        finalpackage.put("partnerid", mchId);
        Long time = (System.currentTimeMillis() / 1000);
        //时间戳
        finalpackage.put("timestamp", time.toString());
        //随机字符串
        finalpackage.put("noncestr", map.get("nonce_str"));
        //预支付交易会话ID
        finalpackage.put("prepayid", map.get("prepay_id"));
        String packages = "Sign=WXPay";
        //扩展字段
        finalpackage.put("package", packages);
        //签名
        String sign = PayCommonUtil.createSign("UTF-8", finalpackage, apiKey);

        WxPrePayResp prePay = new WxPrePayResp();
        prePay.setAppId(appId);
        prePay.setMchId(mchId);
        prePay.setTimeStamp(time.toString());
        prePay.setNonceStr(map.get("nonce_str"));
        prePay.setPrepayId(map.get("prepay_id"));
        prePay.setSignType("MD5");
        prePay.setPaySign(sign);
        prePay.setPackages(packages);
/*        result.setData(prePay);
        result.setStateCode(GeneralConstant.SUCCESS);
        result.setDesc("微信支付加载成功");*/
        // 返回支付相关信息(此处可以直接将getBody中的内容直接返回，无需再做一些其他操作)
        //保存支付类型
        order.setPayType(Constant.PayTypeEnum.WXPAY.getCode());
        orderService.updateById(order);

        return JsonResult.success(prePay);
    }


    @PostMapping("/notify")
    @Transactional
    public String notify(HttpServletRequest request) throws Exception {
        System.out.println("微信支付回调");
        InputStream inStream = request.getInputStream();
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outSteam.write(buffer, 0, len);
        }
        String resultxml = new String(outSteam.toByteArray(), "utf-8");
        Map<String, String> params = PayCommonUtil.doXMLParse(resultxml);
        outSteam.close();
        inStream.close();


        Map<String,String> return_data = new HashMap<String,String>();
        if (!PayCommonUtil.isTenpaySign(params, apiKey)) {
            logger.error("微信回调业务验签报错,params:" + params);
            // 支付失败
            return_data.put("return_code", "FAIL");
            return_data.put("return_msg", "return_code不正确");
            return StringUtil.GetMapToXML(return_data);
        } else {
            System.out.println("===============付款成功==============");
            // ------------------------------
            // 处理业务开始
            // ------------------------------
            // 此处处理订单状态，结合自己的订单数据完成订单状态的更新
            // ------------------------------

            String total_fee = params.get("total_fee");
            double v = Double.valueOf(total_fee) / 100;
            String out_trade_no = String.valueOf(params.get("out_trade_no"));
//            Date accountTime = DateUtil.stringtoDate(params.get("time_end"), "yyyyMMddHHmmss");
//            String ordertime = DateUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss");
//            String totalAmount = String.valueOf(v);
//            String appId = params.get("appid");
            String tradeNo = params.get("transaction_id");
            // 处理支付成功逻辑
            try {
                if(out_trade_no.startsWith(Constant.REWARD_OUT_TRADE_NO_PRE)){
                    //订单评价打赏回调
                    OrderEvaluate orderEvaluate = orderEvaluateService.findByOutTradeNo(out_trade_no);
                    if(orderEvaluate != null){
                        //完成师傅余额增长
                        //修改余额
                        User user = userService.getById(orderEvaluate.getMasterId());
                        BigDecimal balance = Optional.ofNullable(orderEvaluate.getReward()).orElse(BigDecimal.ZERO).add(user.getAccountBalance());
                        user.setAccountBalance(balance);
                        if(userService.updateById(user)){
                            //保存余额变动明细
                            UserAccountDetail userAccountDetail = new UserAccountDetail();
                            userAccountDetail.setAccountType("1");
                            userAccountDetail.setAccoutWay(Long.parseLong(String.valueOf(orderEvaluate.getPayType())));
                            userAccountDetail.setAmount(orderEvaluate.getReward().toString());
                            userAccountDetail.setCreateDt(new Date());
                            userAccountDetail.setDetailType("2");
                            userAccountDetail.setInOutType("3");
                            userAccountDetail.setTranDesc("订单打赏:"+orderEvaluate.getOrderId());
                            userAccountDetail.setUserId(orderEvaluate.getMasterId());
                            userAccountDetail.setTranAmount(user.getAccountBalance());
                            userAccountDetail.setStatus("0");
                            Order order = orderService.getById(orderEvaluate.getOrderId());
                            userAccountDetail.setOutTradeNo(order.getOrderNo());
                            userAccountDetailService.save(userAccountDetail);
                            //更新状态
                            orderEvaluate.setPayAt(new Date());
                            orderEvaluate.setTransNo(tradeNo);
                            orderEvaluate.setRewardStatus(1);//已支付
                            if(orderEvaluateService.updateById(orderEvaluate)){
                                //通知推送师傅
                                if(orderEvaluate.getMasterId() != null) {
                                    sysMessageService.saveMessage("用户打赏订单", "用户打赏订单[" + orderEvaluate.getOrderId() + "]", true, orderEvaluate.getMasterId());
                                }
                            }
                        }else{
                            logger.error("微信回调业务处理【打赏】，师傅余额变动失败:" + out_trade_no);
                        }
                    }else{
                        logger.error("微信回调业务处理【打赏】，评价数据不存在:" + out_trade_no);
                    }
                }else if(out_trade_no.startsWith(Constant.RECHARGE_TRADE_NO_PRE)){
                    //充用户充值回调
                    UserRecharge userRecharge = userRechargeService.findByOutTradeNo(out_trade_no);
                    if(userRecharge != null){
                        //完成师傅余额增长
                        //修改余额
                        User user = userService.getById(userRecharge.getUserId());
                        BigDecimal balance = Optional.ofNullable(userRecharge.getAmount()).orElse(BigDecimal.ZERO).add(user.getAccountBalance());
                        user.setAccountBalance(balance);
                        if(userService.updateById(user)){
                            //保存余额变动明细
                            UserAccountDetail userAccountDetail = new UserAccountDetail();
                            userAccountDetail.setAccountType("1");
                            userAccountDetail.setAccoutWay(Long.parseLong(String.valueOf(userRecharge.getPayType())));
                            userAccountDetail.setAmount(userRecharge.getAmount().toString());
                            userAccountDetail.setCreateDt(new Date());
                            userAccountDetail.setDetailType("2");
                            userAccountDetail.setInOutType("3");
                            userAccountDetail.setTranDesc("充值");
                            userAccountDetail.setUserId(userRecharge.getUserId());
                            userAccountDetail.setStatus("0");
                            userAccountDetail.setTranAmount(user.getAccountBalance());
                            userAccountDetailService.save(userAccountDetail);
                            //更新状态
                            String trade_no = params.get("trade_no");
                            userRecharge.setPayAt(new Date());
                            userRecharge.setTransNo(trade_no);
                            userRecharge.setStatus(2);//已支付
                            if(userRechargeService.updateById(userRecharge)){
                                //通知推送师傅
                                if(userRecharge.getUserId() != null) {
                                    sysMessageService.saveMessage("用户充值", "用户充值[" + userRecharge.getAmount().toString() + "元]成功到账", true, userRecharge.getUserId());
                                }
                            }
                        }else{
                            logger.error("微信回调业务处理【充值】，用户余额变动失败:" + out_trade_no);
                        }
                    }else{
                        logger.error("微信回调业务处理【充值】，充值记录不存在:" + out_trade_no);
                    }
                }else if(out_trade_no.startsWith(Constant.COLLECTION_OUT_TRADE_NO_PRE)){
                    //订单代收货款回调
                    Order order = orderService.findOrderByCollectionOutTradeNo(out_trade_no);
                    order.setCollectionPayStatus(Constant.CollectionPayStatusEnum.PAYED.getCode());//订单状态设为待接单
                    order.setCollectionTransNo(tradeNo);//交易流水号，退款用
                    order.setUpdateAt(new Date());
                    if (orderService.updateById(order)){
                        //修改订单流程状态
                        MasterOrderAccitity orderAccitity = accitityService.getMasterAccitityByOrderId(order.getId(),null);
                        if(orderAccitity != null) {
                            orderAccitity.setCurrentStatus(MasterConstants.MasterOrderCurrentStatus.STATUS_7.getCode());
                            accitityService.updateById(orderAccitity);
                        }
                        //通知推送师傅
                        if(order.getMasterId() != null) {
                            sysMessageService.saveMessage("用户支付代收货款", "用户支付代收货款：" + order.getCollectionAmount()
                                    + ",订单[" + order.getOrderNo() + "]", true, order.getMasterId());
                        }
                    }
                }else if(out_trade_no.startsWith(Constant.FEE_OUT_TRADE_NO_PRE)){
                    //技术服务费不定价回调
                    Order order = orderService.findOrderByFeeOutTradeNo(out_trade_no);
                    order.setFeePayStatus(Constant.CollectionPayStatusEnum.PAYED.getCode());//订单状态设为待接单
                    order.setFeeTransNo(tradeNo);//交易流水号，退款用
                    order.setUpdateAt(new Date());
                    if (orderService.updateById(order)){
                        //修改订单流程状态
                        MasterOrderAccitity orderAccitity = accitityService.getMasterAccitityByOrderId(order.getId(),null);
                        //不定价技术服务付款成功结束计时
                        orderAccitity.setEndTime(new Date());
                        if(orderAccitity != null) {
                            orderAccitity.setCurrentStatus(MasterConstants.MasterOrderCurrentStatus.STATUS_7.getCode());
                            accitityService.updateById(orderAccitity);
                        }
                        //通知推送师傅
                        if(order.getMasterId() != null) {
                            sysMessageService.saveMessage("用户支付订单服务费", "用户支付订单服务费" + order.getAnyhelpFee()
                                    + ",订单[" + order.getOrderNo() + "]", true, order.getMasterId());
                        }
                    }
                }else if(out_trade_no.startsWith(Constant.OUT_TRADE_NO_PRE)){
                    Order order = orderService.findOrderByOutTradeNo(out_trade_no);
                    order.setStatus(Constant.OrderStatusEnum.WAIT_ACCEPT.getCode());//订单状态设为待接单
                    order.setTransNo(tradeNo);//交易流水号，退款用
                    order.setUpdateAt(new Date());
                    orderService.updateById(order);
                    try {
                        //如果是抢单加人工派单，则给师傅发送通知
                        orderDispatchService.newOrderPush(order);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }else{
                    logger.error("微信回调业务处理,未知的out_trade_no,params:" + params);
                }
            } catch (Exception e) {
                logger.error("微信回调业务处理报错,params:" + params, e);
            }

            return_data.put("return_code", "SUCCESS");
            return_data.put("return_msg", "OK");
            return StringUtil.GetMapToXML(return_data);
        }
    }


    /**
     * 统一下单
     * 应用场景：商户系统先调用该接口在微信支付服务后台生成预支付交易单，返回正确的预支付交易回话标识后再在APP里面调起支付。
     * @param trade_no
     * @param totalAmount
     * @param description
     * @param openid
     * @param request
     * @return
     */
    @SuppressWarnings("unchecked")
    public Map<String, String> weixinPrePay(String trade_no,BigDecimal totalAmount,
                                            String description, String openid, HttpServletRequest request, String tradeType) {
        SortedMap<String, Object> parameterMap = new TreeMap<String, Object>();
        parameterMap.put("appid", appId);  //应用appid
        parameterMap.put("mch_id",mchId);  //商户号
        //parameterMap.put("device_info", "WEB");
        parameterMap.put("nonce_str", PayCommonUtil.getRandomString(32));
        parameterMap.put("body", description);
        parameterMap.put("out_trade_no", trade_no);
        parameterMap.put("fee_type", "CNY");
        BigDecimal total = totalAmount.multiply(new BigDecimal(100));  //接口中参数支付金额单位为【分】，参数值不能带小数，所以乘以100
        java.text.DecimalFormat df=new java.text.DecimalFormat("0");
        parameterMap.put("total_fee", df.format(total));
        //parameterMap.put("total_fee", "1");//测试使用0.01
        parameterMap.put("spbill_create_ip", PayCommonUtil.getRemoteHost(request));
        parameterMap.put("notify_url", notify);
        parameterMap.put("trade_type",tradeType);//"JSAPI", "APP"
        //trade_type为JSAPI是 openid为必填项
        //parameterMap.put("openid", openid);
        String sign = PayCommonUtil.createSign("UTF-8", parameterMap, apiKey);
        parameterMap.put("sign", sign);
        String requestXML = PayCommonUtil.getRequestXml(parameterMap);
        System.out.println(requestXML);
        String result = PayCommonUtil.httpsRequest(
                "https://api.mch.weixin.qq.com/pay/unifiedorder", "POST",
                requestXML);
        System.out.println(result);
        Map<String, String> map = null;
        try {
            map = PayCommonUtil.doXMLParse(result);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return map;
    }


    /**
     * 支付订单退款
     * @param order
     * @return
     */
    @Transactional
    public boolean refound(Order order, BigDecimal amount){
        // 调用微信支付退款接口;
        SecapiPayRefund payRefund = new SecapiPayRefund();
        payRefund.setAppid(appId);
        payRefund.setMch_id(mchId);
        payRefund.setNonce_str(PayCommonUtil.getRandomString(32));
        payRefund.setOut_trade_no(order.getOutTradeNo());//支付订单号
        String refundNo = UUID.randomUUID().toString().replaceAll("-", "");
        logger.error("微信退款接口--接口请求状态(退款订单号):" + refundNo);
        payRefund.setOut_refund_no(refundNo);//退款单号
        //测试用0.01
        //payRefund.setTotal_fee(1);//原订单金额,单位:分;
        payRefund.setTotal_fee(order.getAmount().multiply(new BigDecimal(100)).intValue());//原订单金额,单位:分;
        if(amount == null){
            payRefund.setRefund_fee(order.getAmount().multiply(new BigDecimal(100)).intValue());//退款订单金额,单位:分;
        }else{
            payRefund.setRefund_fee(amount.multiply(new BigDecimal(100)).intValue());//退款订单金额,单位:分;
        }
        Map<String, String> map = MapUtil.objectToMap(payRefund, new String[0]);
        String sign = SignatureUtil.generateSign(map, apiKey);
        payRefund.setSign(sign);

//        XStream xStream = new XStream(new XppDriver(new XmlFriendlyNameCoder("_-", "_"))); //<span style="color:#ff0000;"><strong>说明3(见文末)</strong></span>
//        xStream.alias("xml", SecapiPayRefund.class);//根元素名需要是xml
//        String secapiPayRefundXML = xStream.toXML(payRefund);
//        System.out.println(secapiPayRefundXML);
//        RefundOrderRespose unifiedOrderRespose = PayCommonUtil.httpOrder(secapiPayRefundXML);

        //根据微信文档return_code 和result_code都为SUCCESS的时候才会返回code_url
        //<span style="color:#ff0000;"><strong>说明4(见文末)</strong></span>

        // 加载商户支付证书文件;
        //static {
            LocalHttpClient.initMchKeyStore(mchId, API_CLIENT_CERT_PATH);
       // }

        SecapiPayRefundResult refundResult = PayMchAPI.secapiPayRefund(payRefund, apiKey);
         //微信支付退款接口返回数据验签;
        if (refundResult != null && refundResult.getSign_status() != null && refundResult.getSign_status()) {
            logger.error("微信退款接口--接口请求状态(return_code):" + refundResult.getReturn_code());
            logger.error("微信退款接口--接口请求状态(return_msg):" + refundResult.getReturn_msg());

            // 退款信息提交成功;
            if ("SUCCESS".equals(refundResult.getReturn_code())) {
                logger.error("微信退款接口--接口请求状态(result_code):" + refundResult.getResult_code());
                logger.error("微信退款接口--接口请求状态(err_code):" + refundResult.getErr_code());
                logger.error("微信退款接口--接口请求状态(err_code_des):" + refundResult.getErr_code_des());
                return Boolean.TRUE;
            }
        }
        return Boolean.FALSE;
    }


    @ApiOperation(value = "生成APP支付二维码信息（代收货款）", notes="返回二维码对应的url，自行生成二维码")
    @PostMapping("/qrcode")
    @ApiImplicitParam(name = "orderNo", value = "订单号", required = true, dataType = "string")
    public JsonResult qrcode(@RequestParam String orderNo, HttpServletRequest request){
        // 获取项目中实际的订单的信息
        // 此处是相关业务代码
        Order order = orderService.findOrderByOrderNo(orderNo);
        if(order == null){
            throw new ServerInternalErrorException(ErrorEnum.ORDER_NOT_EXIST);
        }
        //String type = DictUtil.keyValue("SERVICE_CLASS",order.getType()+"");
        //String childTypeCode = "SERVICE_CLASS_"+order.getType();
        //String childType = DictUtil.keyValue(childTypeCode,order.getType()+"");
        String subject = "阿四服务订单"+"-代收货款";

        if(order.getCollectionAmount() == null || order.getCollectionAmount().compareTo(BigDecimal.ZERO)<=0){
            //如果有代收货款
            throw new ServerInternalErrorException(ErrorEnum.NO_COLLECTION_AMOUNT);
        }

        /*Unifiedorder unifiedorder = new Unifiedorder();
        *//** APPID *//*
        unifiedorder.setAppid(appId);
        *//** 商户号 *//*
        unifiedorder.setMch_id(mchId);
        *//** 随机字符串 *//*
        unifiedorder.setNonce_str(PayCommonUtil.getRandomString(32));
        *//** 商品描述 *//*
        unifiedorder.setBody(subject);
        *//** 商户订单号 *//*
        unifiedorder.setOut_trade_no(order.getOutTradeNo());
        *//** 订单总金额 *//*
        BigDecimal total = order.getAmount().multiply(new BigDecimal(100));  //接口中参数支付金额单位为【分】，参数值不能带小数，所以乘以100
        java.text.DecimalFormat df=new java.text.DecimalFormat("0");
        unifiedorder.setTotal_fee(df.format(total));   // 订单总金额,单位为分;
        *//** 用户端请求IP地址 *//*
        unifiedorder.setSpbill_create_ip(PayCommonUtil.getRemoteHost(request));
        *//** 异步通知回调地址 *//*
        unifiedorder.setNotify_url(notify);
        *//** 交易类型 *//*
        unifiedorder.setTrade_type("APP");
        //logger.warn("微信APP支付--(签名前):" + XMLConverUtil.convertToXML(unifiedorder));
        *//** 获取签名 *//*
        UnifiedorderResult unifiedorderResult = PayMchAPI.payUnifiedorder(unifiedorder, apiKey);
        logger.warn("微信APP支付--支付统一下单接口请求状态(return_code):" + unifiedorderResult.getReturn_code());
        logger.warn("微信APP支付--支付统一下单接口请求状态(return_msg):" + unifiedorderResult.getReturn_msg());
        logger.warn("微信APP支付--支付统一下单接口请求状态(result_code):" + unifiedorderResult.getResult_code());
        logger.warn("微信APP支付--支付请求参数封装(签名后):" + XMLConverUtil.convertToXML(unifiedorder));
        //logger.warn("微信APP支付--支付统一下单接口返回数据:" + FastJSONUtils.getJsonHelper().toJSONString(unifiedorderResult));
        // 下单结果验签;
        if(unifiedorderResult.getSign_status() != null && unifiedorderResult.getSign_status()) {
            logger.warn("微信APP支付验签成功");
            return JsonResult.success(unifiedorderResult.getCode_url());
            //return PayUtil.generateMchAppData(unifiedorderResult.getPrepay_id(), APPID, MCH_ID, PRIVATE_KEY);
        }*/


        //BigDecimal totalAmount = new BigDecimal(request.getParameter("totalPrice"));
        String trade_no = "";
        try {
            trade_no = new String(order.getCollectionOutTradeNo().getBytes("ISO-8859-1"),"UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return JsonResult.failure("失败");
        }
        String openId = "";
        Map<String, String> map = weixinPrePay(trade_no,order.getCollectionAmount(),subject,openId,request, "NATIVE");
        order.setPayType(Constant.PayTypeEnum.WXPAY.getCode());
        order.setCollectionPayStatus(2);
        orderService.updateById(order);

        /*Map maps = new HashMap();
        maps.put("amount",order.getCollectionAmount());
        maps.put("qrCode",map);*/
        map.put("amount",order.getCollectionAmount().toString());

        return JsonResult.success(map);
    }

    @ApiOperation(value = "生成APP支付二维码信息（技术服务不定价收款）", notes="返回二维码对应的url，自行生成二维码")
    @PostMapping("/qrcodeForFee")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderNo", value = "订单号", required = true, dataType = "string"),
            @ApiImplicitParam(name = "fee", value = "技术服务费（不定价）", required = true, dataType = "string")
    })
    public JsonResult qrcodeForFee(@RequestParam String orderNo, @RequestParam BigDecimal fee, HttpServletRequest request){
        // 获取项目中实际的订单的信息
        // 此处是相关业务代码
        Order order = orderService.findOrderByOrderNo(orderNo);
        if(order == null){
            throw new ServerInternalErrorException(ErrorEnum.ORDER_NOT_EXIST);
        }

        if(fee == null || fee.compareTo(BigDecimal.ZERO)<=0){
            throw new ServerInternalErrorException(ErrorEnum.PARAM_VALID_ERROR);
        }

        if(order.getFeeOutTradeNo() == null){
            throw new ServerInternalErrorException(ErrorEnum.PARAM_VALID_ERROR);
        }

        String subject = "阿四服务订单"+"-技术服务费";

        //BigDecimal totalAmount = new BigDecimal(request.getParameter("totalPrice"));
        String trade_no = "";
        try {
            trade_no = new String(order.getFeeOutTradeNo().getBytes("ISO-8859-1"),"UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return JsonResult.failure("失败");
        }
        String openId = "";
        Map<String, String> map = weixinPrePay(trade_no,fee,subject,openId,request, "NATIVE");
        order.setAnyhelpFee(fee);
        order.setPayType(Constant.PayTypeEnum.WXPAY.getCode());
        //order.setCollectionPayStatus(2);
        orderService.updateById(order);

        Map maps = new HashMap();
        maps.put("amount",fee);
        maps.put("qrCode",map);
        return JsonResult.success(map);
    }

    @ApiOperation(value = "订单打赏支付参数生成", notes="订单打赏支付参数生成")
    @PostMapping("/reward")
    @ApiImplicitParam(name = "orderNo", value = "订单号", required = true, dataType = "string")
    @Transactional
    public JsonResult reward(@RequestParam String orderNo, HttpServletRequest request){
        Order order = orderService.findOrderByOrderNo(orderNo);
        Optional.ofNullable(order) .orElseThrow(()->new ServerInternalErrorException(ErrorEnum.ORDER_NOT_EXIST));
        OrderEvaluate orderEvaluate = orderEvaluateService.findOneByOrderId(order.getId());
        Optional.ofNullable(orderEvaluate).filter(o->o.getRewardStatus() == 0)
                .orElseThrow(()->new ServerInternalErrorException(ErrorEnum.DATA_NOT_EXIST));
        if(orderEvaluate.getReward() == null || orderEvaluate.getReward().compareTo(BigDecimal.ZERO)<=0){
            throw new ServerInternalErrorException(ErrorEnum.DATA_NOT_EXIST);
        }
        String trade_no = "";
        String description="";
        try {
            trade_no = new String(orderEvaluate.getOutTradeNo().getBytes("ISO-8859-1"),"UTF-8");
            description = "阿四服务订单"+orderEvaluate.getOrderId()+"打赏";
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String openId = "";
        Map<String, String> map = weixinPrePay(trade_no,orderEvaluate.getReward(),description,openId,request, "APP");
        SortedMap<String, Object> finalpackage = new TreeMap<String, Object>();
        //应用ID
        finalpackage.put("appid", appId);
        //商户号
        finalpackage.put("partnerid", mchId);
        Long time = (System.currentTimeMillis() / 1000);
        //时间戳
        finalpackage.put("timestamp", time.toString());
        //随机字符串
        finalpackage.put("noncestr", map.get("nonce_str"));
        //预支付交易会话ID
        finalpackage.put("prepayid", map.get("prepay_id"));
        String packages = "Sign=WXPay";
        //扩展字段
        finalpackage.put("package", packages);
        //签名
        String sign = PayCommonUtil.createSign("UTF-8", finalpackage, apiKey);

        WxPrePayResp prePay = new WxPrePayResp();
        prePay.setAppId(appId);
        prePay.setMchId(mchId);
        prePay.setTimeStamp(time.toString());
        prePay.setNonceStr(map.get("nonce_str"));
        prePay.setPrepayId(map.get("prepay_id"));
        prePay.setSignType("MD5");
        prePay.setPaySign(sign);
        prePay.setPackages(packages);
        //保存支付类型
        orderEvaluate.setPayType(Constant.PayTypeEnum.WXPAY.getCode());
        orderEvaluateService.saveOrUpdate(orderEvaluate);

        return JsonResult.success(prePay);
    }


    @ApiOperation(value = "用户充值支付参数生成", notes="用户充值支付参数生成")
    @PostMapping("/recharge")
    @ApiImplicitParam(name = "amount", value = "金额", required = true, dataType = "string")
    @Transactional
    public JsonResult recharge(@RequestParam BigDecimal amount){
        if(amount == null){
            throw new ServerInternalErrorException(ErrorEnum.PARAM_VALID_ERROR);
        }
        String trade_no = "";
        String description="";
        try {
            trade_no =  new String(CommonUtil.generateOrderNum(Constant.RECHARGE_TRADE_NO_PRE, getUserId()).getBytes("ISO-8859-1"),"UTF-8");
            description = "阿四服务充值订单："+amount.toString();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String openId = "";
        Map<String, String> map = weixinPrePay(trade_no,amount,description,openId,request, "APP");
        SortedMap<String, Object> finalpackage = new TreeMap<String, Object>();
        //应用ID
        finalpackage.put("appid", appId);
        //商户号
        finalpackage.put("partnerid", mchId);
        Long time = (System.currentTimeMillis() / 1000);
        //时间戳
        finalpackage.put("timestamp", time.toString());
        //随机字符串
        finalpackage.put("noncestr", map.get("nonce_str"));
        //预支付交易会话ID
        finalpackage.put("prepayid", map.get("prepay_id"));
        String packages = "Sign=WXPay";
        //扩展字段
        finalpackage.put("package", packages);
        //签名
        String sign = PayCommonUtil.createSign("UTF-8", finalpackage, apiKey);

        WxPrePayResp prePay = new WxPrePayResp();
        prePay.setAppId(appId);
        prePay.setMchId(mchId);
        prePay.setTimeStamp(time.toString());
        prePay.setNonceStr(map.get("nonce_str"));
        prePay.setPrepayId(map.get("prepay_id"));
        prePay.setSignType("MD5");
        prePay.setPaySign(sign);
        prePay.setPackages(packages);

        //保存充值记录
        UserRecharge ur = new UserRecharge();
        ur.setAmount(amount);
        ur.setOutTradeNo(trade_no);
        ur.setCreateAt(new Date());
        ur.setDeleteState(1);//正常
        //保存支付类型
        ur.setPayType(Constant.PayTypeEnum.ALIPAY.getCode());
        ur.setStatus(1);//支付中
        ur.setUserId(getUserId());
        userRechargeService.save(ur);

        return JsonResult.success(prePay);
    }
}
